import { getModules } from '../../api/system-setting.js'

/**
 * convert modules to routes
 * @param modules
 * @returns {Array}
 */
function convertToRoutes(modules) {
  const routes = []
  modules.forEach((module) => {
    // eslint-disable-next-line no-unused-vars
    const {
      fullName: name,
      urlAddress: path,
      redirect,
      description: title,
      icon
    } = module.module
    const tmp = {
      name,
      path,
      redirect,
      meta: { title, icon }
    }
    if (module.children) {
      tmp.alwaysShow = true
      tmp.children = convertToRoutes(module.children)
    }
    routes.push(tmp)
  })

  return routes
}

/**
 * format roles
 * @param roles
 * @returns {Array}
 */
function getUniqueModules(roles) {
  const modules = []
  roles.forEach((role) => {
    role.securityModules
      .map((module) => module.module)
      .forEach((module) => {
        if (!modules.some((item) => item.id === module.id)) {
          modules.push(module)
        }
      })
  })
  return modules
}

function getOrganizationNumber(organizationTree) {
  let number = 0
  organizationTree.forEach((node) => {
    if (node.children) {
      number += node.children.length
    }
  })
  return number
}

/**
 * use meta.role to determine if the current user has permission
 * @param roles
 * @param route
 */
function hasPermission(roleModules, module) {
  if (roleModules.some((rm) => rm.id === module.module.id)) return true
  if (module.children) {
    if (module.children.some((m) => hasPermission(roleModules, m))) return true
  }
  return false
}

/**
 * filter asynchronous routing tables by recursion
 * @param routes asyncRoutes
 * @param roles
 */
export function filterAsyncModules(modules, roleModules) {
  const res = []
  modules.forEach((module) => {
    const tmp = { ...module }
    if (hasPermission(roleModules, tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncModules(tmp.children, roleModules)
      }
      res.push(tmp)
    }
  })

  return res
}

const state = {
  routes: [],
  addRoutes: [],
  organizationNumber: 0
}

const mutations = {
  SET_ROUTES: (state, routes) => {
    state.routes = routes
  },
  SET_ORGANIZATION_TREE: (state, organizationTree) => {
    state.organizationTree = organizationTree
    state.organizationNumber = getOrganizationNumber(organizationTree)
  }
}

const actions = {
  generateRoutes({ commit }, roles) {
    return getModules().then((response) => {
      const modules = response.data.pageItems
      if (!modules) return []
      let accessedRoutes
      if (roles.some((role) => role.roleName === 'ROLE_ADMIN')) {
        accessedRoutes = convertToRoutes(modules)
      } else {
        accessedRoutes = convertToRoutes(
          filterAsyncModules(modules, getUniqueModules(roles))
        )
      }
      commit('SET_ROUTES', accessedRoutes)
      return accessedRoutes
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}
